
#pragma once

#include "NetworkActionBase.hpp"
#include <functional>
#include <deque>

CYBERTRON_BEGIN

class NetworkActionExecuter : public std::enable_shared_from_this<NetworkActionExecuter>
{
public:
	CybertronCoreAPI NetworkActionExecuter();
	CybertronCoreAPI ~NetworkActionExecuter();

	CybertronCoreAPI void initialize(
		std::shared_ptr<SocketBase> pSocket,
		int millisecondsTimeout);
	CybertronCoreAPI void onTimer(int ms);
	CybertronCoreAPI void onMessage(Message& msg);
	CybertronCoreAPI void clear();

	CybertronCoreAPI void queueAction(
		std::uint16_t desiredMsgId,
		std::shared_ptr<NetworkActionBase> pAction, 
		int timeoutMilliseconds);
	CybertronCoreAPI void queueAction(
		std::uint16_t desiredMsgId,
		std::shared_ptr<NetworkActionBase> pAction);
	CybertronCoreAPI void queueAction(
		std::uint16_t desiredMsgId,
		std::function<void()> funcOnStart, 
		std::function<void(Message&)> funcOnDesiredMessage, 
		std::function<void()> funcOnTimeout);

	CybertronCoreAPI bool isBusy() const;

private:
	void zeroMembers();
	std::shared_ptr<NetworkActionBase> getActiveAction();

private:
	NetworkActionExecuter(const NetworkActionExecuter&);
	NetworkActionExecuter& operator = (const NetworkActionExecuter&);

private:
	std::weak_ptr<SocketBase> mpSocket;
	int mMillisecondsTimeout;
	std::shared_ptr<NetworkActionBase> mpCurrentAction;
	std::deque<std::shared_ptr<NetworkActionBase>> mActions;
};

CYBERTRON_END
